/* eslint-disable no-useless-escape */
import router from '../router'
import EventBus from './EventBus'
import { Modal, Spin } from 'view-design'

import html2canvas from 'html2canvas'
import _ from 'lodash'
import $ from 'jquery'

import store from '../store/index'

/**
 * 生成UUID
 * @returns {string}
 */
const uuid = function() {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return (S4() + S4() + "" + S4() + "" + S4() + "" + S4() + "" + S4() + S4() + S4());
};

/**
 * 获取当前时间戳
 * @returns {number}
 */
const getTimestamp = function () {
  return new Date().getTime();
};

/**
 * Date格式化
 * @param date
 * @param fmt
 * @returns {*}
 */
const dateFormatter = function (date, fmt) {
  let o = {
    "M+": date.getMonth() + 1, //月份
    "d+": date.getDate(), //日
    "h+": date.getHours(), //小时
    "m+": date.getMinutes(), //分
    "s+": date.getSeconds(), //秒
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
    "S": date.getMilliseconds() //毫秒
  };
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (let k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  return fmt;
}

/**
 * PageNow中打开一个新的页面
 * @param path
 * @param query
 */
const openPageToBlank = function (path, query) {
  let routeUrl = router.resolve({
    path: path,
    query: query
  });
  window.open(routeUrl.href, '_blank');
};

/**
 * 获取项目工程根路径
 * @returns {*}
 */
const getRootPath = function () {
  let curWwwPath = window.document.location.href;
  let pathName = window.document.location.pathname;
  let pos = curWwwPath.indexOf(pathName);
  let localhostPath = curWwwPath.substring(0, pos);
  let projectName = pathName.substring(0, pathName.substr(1).indexOf('/')+1);
  return localhostPath + projectName
}

/**
 * 跳转链接
 * @param href
 * @param target
 */
const jumpLink = function (href, target = '_self') {
  switch (target) {
    case '_self':
      window.location.href = href.replace('${BASE_PATH}', BASE_PATH);
      break;
    case '_blank':
      window.open(href.replace('${BASE_PATH}', BASE_PATH));
      break;
  }
};

/**
 * 打开一个模态窗显示IFrame，此函数一般在页面发布运行时使用
 * @param src
 * @param width
 * @param height
 * @param scrolling 默认为auto
 */
const openIframeModal = function (src, width, height, scrolling = 'auto') {
  let documentHeight = $(document).height(); // 浏览器窗口高度
  let iframeHeight = null;
  if (height && height.indexOf('%') > -1) {
    iframeHeight = (documentHeight * parseInt(height)/100) - 95
  }else if (height && height.indexOf('px') > -1) {
    iframeHeight = height
  }else {
    iframeHeight = 'auto'
  }
  Modal.info({
    width: width,
    okText: '关闭',
    render: (h) => {
      return h('iframe', {
        attrs: {
          src: src,
          frameborder: 0,
          width: '100%',
          height: iframeHeight,
          scrolling: scrolling
        }
      })
    }
  });
  $('.ivu-modal-wrap').css('display', 'flex').css('align-items', 'center').css('justify-content', 'center');
  $('.ivu-modal-wrap .ivu-modal').css('top', '0px')
};

/**
 * 获取反色差值
 * @param hexcolor (示例：FFFFFF)
 * @returns {string}
 */
const getContrastYIQ = function (hexcolor) {
  let r = parseInt(hexcolor.substr(0,2),16);
  let g = parseInt(hexcolor.substr(2,2),16);
  let b = parseInt(hexcolor.substr(4,2),16);
  let yiq = ((r*299)+(g*587)+(b*114))/1000;
  return (yiq >= 128) ? 'black' : 'white';
};

/**
 * 判断是否为Mac系统
 * @returns {*|boolean}
 */
const isMac = function () {
  return /macintosh|mac os x/i.test(navigator.userAgent);
};

/**
 * 判断是否为Windows系统
 * @returns {*|boolean}
 */
const isWindows = function () {
  return /windows|win32/i.test(navigator.userAgent);
};

/**
 * 删除iView的Table中行数据的一些前端无用字段，提供给后端JFinal更新使用
 * @param obj
 * @returns {*}
 */
const deleteTableRowUselessField = function (obj) {
  if(obj) {
    let newObj = Object.assign({}, obj);
    delete newObj._index;
    delete newObj._rowKey;
    delete newObj.username;
    return newObj
  }
  return null
};

/**
 * css样式文本转Vue专用的Style对象
 * @param cssStr
 */
const cssToVueStyleObj = function (cssStr) {
  let styleObj = {};

  if (cssStr) {
    // 去除换行
    // cssStr = cssStr.replace(/\ +/g, '').replace(/[\r\n]/g, '');
    cssStr = cssStr.replace(/[\r\n]/g, '');
    // 去除 '{' 和 '}'
    cssStr = cssStr.replace('{','').replace('}','');

    // 拆分样式项并组成样式项数组
    let cssItems = cssStr.split(';');

    cssItems.forEach(cssItem => {
      if(cssItem) {
        let attr = '';
        if (cssItem.split(':')[0]) {
          attr = cssItem.split(':')[0].trim(); // 样式项键（运行trim去除首位空格）
        }
        let val = '';
        if (cssItem.split(':')[1]) {
          val = cssItem.split(':')[1].trim();  // 样式项值（运行trim去除首位空格）
        }

        // 定义一个数组存储属性键中'-'出现的位置
        let positions = [];
        let pos = attr.indexOf('-');
        while (pos > -1) {
          positions.push(pos);
          pos = attr.indexOf('-', pos + 1);
        }

        if(positions.length > 0) {
          // 定义一个数组存储每一次出现'-'符号时要处理的替换数据
          let replaceArr = [];
          for (let i=0; i<positions.length; i++) {
            // 待替换字符
            let awaitReplaceStr = attr.substring(positions[i], positions[i]+2);
            // 替换的字符
            let newStr = attr.substring(positions[i]+1, positions[i]+2);

            replaceArr.push({
              awaitReplaceStr: awaitReplaceStr,
              newStr: newStr.toLocaleUpperCase() //替换的字符要转成大写
            });
          }

          replaceArr.forEach(item=>{
            attr = attr.replace(item.awaitReplaceStr, item.newStr)
          })
        }

        styleObj[attr] = val

      }
    });
  }

  return styleObj;
};

/**
 * 深拷贝对象
 * @param obj
 * @returns {any}
 */
const deepClone = function (obj) {
  // let objStr = JSON.stringify(obj);
  // let cloneObj = JSON.parse(objStr);
  // return cloneObj
  return _.cloneDeep(obj)
};

/**
 * 动态添加URL参数
 * @param key
 * @param value
 */
const addUrlParams = function (key, value) {
  let uri = window.location.href;

  let re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  let separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    uri = uri.replace(re, '$1' + key + "=" + value + '$2');
  }else {
    uri = uri + separator + key + "=" + value;
  }
  window.history.replaceState({
    path: uri
  }, '', uri);
};

/**
 * 动态删除URL参数
 * @param name
 */
const deleteUrlParams = function (name) {
  let loca = window.location;
  let baseUrl = loca.origin + loca.pathname + "?";
  let query = loca.search.substr(1);
  if (query.indexOf(name)>-1) {
    let obj = {};
    let arr = query.split("&");
    for (let i = 0; i < arr.length; i++) {
      arr[i] = arr[i].split("=");
      obj[arr[i][0]] = arr[i][1];
    }
    delete obj[name];
    let url = baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g,"").replace(/\:/g,"=").replace(/\,/g,"&");
    window.history.replaceState({
      path: url
    }, '', url);
  }
};

/**
 * 获取URL参数值
 * @param name
 * @returns
 */
const getUrlParam  = function (name) {
  let query = window.location.search.substring(1);
  let vars = query.split("&");
  for (let i = 0; i<vars.length; i++) {
    let pair = vars[i].split("=");
    if(pair[0] == name){ return pair[1]; }
  }
  return undefined;
};

/**
 * 构建接口地址
 * @param apiPath 接口地址
 * @param linkageUrlParams 联动参数集合
 * @returns {*}
 */
const buildApiPath = function (apiPath, linkageUrlParams) {
  let params = '';
  for(let q in router.history.current.query) {
    linkageUrlParams.forEach(item=>{
      if (item.field == q) {
        params += '&' + q + '=' + router.history.current.query[q] + ''
      }
    });
  }
  params = params.substr(0, params.length);

  if (linkageUrlParams.length == 0) {
    return apiPath
  }else {
    if(apiPath.indexOf('?') > 0) {
      apiPath += params;
    }else {
      apiPath += '?' + params;
    }
    return apiPath;
  }
};

/**
 * 获取组件的compConfigData默认配置数据
 * @param compName
 * @returns {*}
 */
const getCompConfigData = function (compName) {
  let compConfigData = null;
  const componentsContext = require.context('../components/', true, /\.vue$/);

  componentsContext.keys().forEach(fileName => {
    const componentConfig = componentsContext(fileName);

    if(componentConfig.default.name == compName) {
      const compInst = require('../components/'+fileName.slice(2, fileName.length));
      compConfigData = Object.assign({}, compInst.default.attr.configDataTemp)
    }
  });

  return compConfigData
};

/**
 * 获取组件attr配置，不获取compConfigData数据
 * @param compName
 * @returns {*}
 */
const getCompBaseAttr = function (compName) {
  let baseAttr = {
    version: ''
  };
  const componentsContext = require.context('../components/', true, /\.vue$/);

  componentsContext.keys().forEach(fileName => {
    const componentConfig = componentsContext(fileName);

    if(componentConfig.default.name == compName) {
      const compInst = require('../components/'+fileName.slice(2, fileName.length));
      if (compInst.default.attr.version !== undefined) {
        baseAttr.version = compInst.default.attr.version
      }
    }
  });

  return baseAttr
};

/**
 * 获取FunctionalComponents文件夹下所有功能组件的文件名（已排除掉了配置表单文件名）
 * @returns {Array}
 */
const getAllFuncCompName = function () {
  let arr = [];
  const componentsContext = require.context('../components/functional/', true, /\.vue$/);

  componentsContext.keys().forEach(fileName => {
    const componentConfig = componentsContext(fileName);
    if (componentConfig.default.name.indexOf('Form') < 0) {
      arr.push(componentConfig.default.name)
    }
  });
  return arr;
};

/**
 * 客户端下载图片工具对象
 */
const img = {
  download(imgData, name) {
    this.downloadFile(name ? name : 'test', imgData);
  },
  //下载
  downloadFile(fileName, content) {
    let aLink = document.createElement('a');
    let blob = this.base64ToBlob(content); //new Blob([content]);

    let evt = document.createEvent("HTMLEvents");
    evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错  事件类型，是否冒泡，是否阻止浏览器的默认行为
    aLink.download = fileName + ".png";
    aLink.href = URL.createObjectURL(blob);

    // aLink.dispatchEvent(evt);
    document.getElementsByTagName('body')[0].appendChild(aLink);//火狐浏览器添加项
    aLink.click();
    document.getElementsByTagName('body')[0].removeChild(aLink);
  },
  //base64转blob
  base64ToBlob(code) {
    let parts = code.split(';base64,');
    let contentType = parts[0].split(':')[1];
    let raw = window.atob(parts[1]);
    let rawLength = raw.length;

    let uInt8Array = new Uint8Array(rawLength);

    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
  },
};

/**
 * 图片转base64
 * @param imgSrc 图片路径
 * @param ext 后缀
 * @param callback 回调函数
 */
const imageToBase64 = function (imgSrc, ext, callback) {
  let canvas = document.createElement("canvas"); //创建canvas DOM元素
  let ctx = canvas.getContext("2d");
  let img = new Image();
  img.crossOrigin = 'anonymous';
  img.src = imgSrc + '?v=' + Math.random();
  img.onload =  function () {
    canvas.width = img.width; //指定画板的宽度，自定义
    canvas.height = img.height; //指定画板的高度,自定义
    ctx.drawImage(img, 0, 0, img.width, img.height); //参数可自定义
    let dataURL = canvas.toDataURL("image/" + ext);
    callback.call(this, dataURL); //回掉函数获取Base64编码
    canvas = null;
  }
};

/**
 * 深合并对象
 * @param obj1
 * @param obj2
 */
const deepMerge = function (obj1, obj2) {
  let key;
  for(key in obj2) {
    // 如果target(也就是obj1[key])存在，且是对象的话再去调用deepMerge，否则就是obj1[key]里面没这个对象，需要与obj2[key]合并
    obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
      deepMerge(obj1[key], obj2[key]) : obj1[key] = obj2[key];
  }
  return obj1;
};

/**
 * 添加图片相对路径至本地存储
 * @param relativePath
 */
const addImageToLocalStorage = function (relativePath) {
  if (!localStorage.getItem('uploadImageRecord')) {
    localStorage.setItem('uploadImageRecord', '[]')
  }
  let uploadImageRecord = JSON.parse(localStorage.getItem('uploadImageRecord'));
  uploadImageRecord.unshift({
    relativePath: relativePath
  });
  localStorage.setItem('uploadImageRecord', JSON.stringify(uploadImageRecord));
  EventBus.$emit('pn_uploadImageRecordChange');
};

/**
 * 获取当前登录用户信息
 * @returns {*}
 */
const getCurrentUser = function () {
  let currentUser = JSON.parse(localStorage.getItem('current_user'));
  if (currentUser) {
    return currentUser
  }else {
    return null
  }
};

/**
 * 获取浏览器内核与版本号
 */
const getBrowser = function () {
  let sys = {};
  let ua = navigator.userAgent.toLowerCase();
  let re = /(msie|firefox|chrome|opera|version).*?([\d.]+)/;
  let m = ua.match(re);
  try {
    sys.browser = m[1].replace(/version/, "safari");
    sys.version = m[2];
  } catch (e) {
    console.log("无法获取浏览器信息")
  }
  return sys;
};

/**
 * 删减字符串，结尾使用...替代
 * @param str
 * @param threshold 阈值
 * @returns {string|*}
 */
const cutString = function (str, threshold) {
  if (str.length > threshold) {
    return str.substring(0, threshold) + '..'
  }
  return str
};

/**
 * 根据相对路径，构建图片绝对路径
 * @param relativePath
 * @returns {string}
 */
const buildImageSrc = function (relativePath) {
  return window.g.AXIOS_BASE_URL + relativePath
};

/**
 * 如果Drawer组件需要显示底部栏，那么则需要使用此函数构建Drawer的styles属性
 * @returns {{overflow: string, paddingBottom: string, position: string, height: string}}
 */
const buildDrawerStyleByHasFooter = function () {
  return {
    height: 'calc(100% - 50px)',
    overflow: 'auto',
    paddingBottom: '50px',
    position: 'static'
  }
};

/**
 * 重构Layout对象，在新建页面使用模板的时候，通过此方法重构layout对象，重置相关的ID
 * @param layout
 * @returns {any}
 */
const reconsitutionLayoutObj = function (layout) {
  let newLayout = deepClone(layout);

  newLayout.id = uuid();

  if (newLayout.layoutGroup) {
    // 先遍历组，将所有组关联的布局块的ID重构
    for (let i=0; i < newLayout.layoutGroup.length; i++) {
      for (let j=0; j < newLayout.layoutGroup[i].layoutItemIds.length; j++) {
        for (let k=0; k < newLayout.layoutItems.length; k++) {
          if (newLayout.layoutItems[k].id == newLayout.layoutGroup[i].layoutItemIds[j]) {
            let newUuid = uuid()
            newLayout.layoutGroup[i].layoutItemIds[j] = newUuid;
            newLayout.layoutItems[k].id = newUuid;
          }
        }
      }
    }
    // 收集所有组关联的布局块ID，存入一个集合数组中
    let allGroupLayoutItemIds = [];
    for (let i=0; i < newLayout.layoutGroup.length; i++) {
      allGroupLayoutItemIds = allGroupLayoutItemIds.concat(newLayout.layoutGroup[i].layoutItemIds)
    }

    // 遍历所有布局块，如果布局块没有被成组，那么直接重设布局块的ID
    for (let i=0; i < newLayout.layoutItems.length; i++) {
      if (allGroupLayoutItemIds.indexOf(newLayout.layoutItems[i].id) == -1) {
        newLayout.layoutItems[i].id = uuid();
      }
    }
  }

  // 遍历所有布局块，判断是否关联了组件，如果关联了，将组件的ID重构
  for (let i=0; i < newLayout.layoutItems.length; i++) {
    if (newLayout.layoutItems[i].component.id) {
      newLayout.layoutItems[i].component.id = uuid()
    }
  }

  return newLayout

};

/**
 * 数组分组
 * @param list 源数组
 * @param field 需要分组的字段名
 * @returns [{type: '', list: []},{type: '', list: []}]
 */
const groupArray = function (list, field) {
  let fieldList = [], att = [];
  list.map((e) => {
    fieldList.push(e[field])
  });
  //数组去重
  fieldList = fieldList.filter((e, i, self) => {
    return self.indexOf(e) == i
  });

  for (let j = 0; j < fieldList.length; j++) {
    //过滤出匹配到的数据
    let arr = list.filter((e) => {
      return e[field] == fieldList[j];
    });
    att.push({
      type: arr[0][field],
      list: arr
    })
  }
  return att;
};

/**
 * 在文本表单组件中获取光标位置并插入值
 * @param documentObj 通过document.getElementById获取的文本表单组件对象
 * @param text 插入的文本值
 */
const insertTextAtCursor = function (documentObj, text) {
  // IE
  if (document.selection) {
    documentObj.focus();
    let sel = document.selection.createRange();
    sel.text = text;
    sel.select();
  }
  // 非IE
  else if (documentObj.selectionStart || documentObj.selectionStart == '0') {
    let startPos = documentObj.selectionStart;
    let endPos = documentObj.selectionEnd;
    // save scrollTop before insert www.keleyi.com
    let restoreTop = documentObj.scrollTop;
    documentObj.value = documentObj.value.substring(0, startPos) + text + documentObj.value.substring(endPos, documentObj.value.length);
    if (restoreTop > 0) {
      documentObj.scrollTop = restoreTop;
    }
    documentObj.focus();
    documentObj.selectionStart = startPos + text.length;
    documentObj.selectionEnd = startPos + text.length;
  } else {
    documentObj.value += text;
    documentObj.focus();
  }
};

/**
 * 复制文本至剪切板
 * @param cont
 */
const copyToClipboard = function (cont) {
  (function (cont) {
    document.oncopy = function (e) {
      e.clipboardData.setData('text', cont);
      e.preventDefault();
      document.oncopy = null;
    }
  })(cont);
  document.execCommand('Copy');
};

/**
 * 获取范围内随机数
 * @param start 起始值
 * @param end 结束值
 * @param fixed 保留小数位数
 * @returns {*|string}
 */
const getRandomNum = function (start, end, fixed = 0) {
  let differ = end - start;
  let random = Math.random();
  return (start + differ * random).toFixed(fixed)
};

/**
 * 异步链接跳转
 * @param url
 * @param fileName 下载文件的文件名，带后缀
 */
const asyncHref = function (url, fileName) {
  let xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'blob';
  xhr.onload = function () {
    if (this.status == 200) {
      let blob = this.response;
      let reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function (e) {
        let a = document.createElement('a');
        a.download = fileName;
        a.href = e.target.result;
        // 修复firefox中无法触发click的问题
        $('body').append(a);
        a.click();
        $(a).remove();
      }
    }
  };
  xhr.send()
};

/**
 * 显示Spin遮罩层
 * @param state
 */
const showMaskLayer = function (state) {
  if (state) {
    Spin.show({
      render: (h) => {
        return h('div', {
          style: {
            color: '#2196f3'
          }
        }, [
          h('Icon', {
            'class': 'pn-spin-icon-load m-b-10px',
            props: {
              type: 'ios-loading',
              size: 30
            }
          }),
          h('div', '正在努力加载中，请稍候...')
        ])
      }
    })
  }else {
    Spin.hide()
  }
}

/**
 * 根据CSS文本引入样式
 * @param cssText
 */
const insertStyle = function (cssText) {
  let head = document.getElementsByTagName("head")[0];
  let style = document.createElement("style");
  let rules = document.createTextNode(cssText);
  style.type = "text/css";
  if (style.styleSheet) {
    style.styleSheet.cssText = rules.nodeValue;
  } else {
    style.appendChild(rules);
  }
  head.appendChild(style)
}

/**
 * 根据JS文本引入script
 * @param jsText
 */
const insertScript = function (jsText) {
  let script = document.createElement("script");
  script.type = "text/javascript";
  try {
    script.appendChild(document.createTextNode(jsText));
  } catch (ex) {
    script.text = jsText;
  }
  document.body.appendChild(script);
}

/**
 * 动态加载css文件
 * @param url
 * @param isCache
 */
const loadCSS = function (url, isCache = false) {
  let element = document.createElement("link");
  element.setAttribute("rel", "stylesheet");
  element.setAttribute("type", "text/css");
  if (isCache) {
    element.setAttribute("href", url + "?t=" + new Date().getTime());
  } else {
    element.setAttribute("href", url);
  }
  document.head.appendChild(element);
}

/**
 * 获取是否是设计器页面
 * @returns {boolean}
 */
const isDesignerPage = function () {
  if (window.document.location.href.indexOf('/designer') > -1) {
    return true
  }
  return false
}

/**
 * 手动发起内置交互流
 * @param bindingVariateName 发起的交互变量
 * @param value 发送值
 */
const manualLaunchInteractionStream = function (bindingVariateName, value) {
  console.log('正在手动发起内置交互流，发起的交互变量【'+bindingVariateName+'】，发送值【'+value+'】')
  store.commit('common/setInteractionSourceDataItem', {key: bindingVariateName, value: value})
  let sender = {
    type: 'single',
    data: {
      bindingVariateName: bindingVariateName,
      value: value
    }
  }
  EventBus.$emit('pn_interaction_stream_manual', sender)
}

/**
 * 手动发起一组内置交互流
 * @param interactionStreams 数组项: {bindingVariateName: '', value: ''}
 */
const multiManualLaunchInteractionStream = function (interactionStreams = []) {
  try {
    interactionStreams.forEach(item => {
      store.commit('common/setInteractionSourceDataItem', {key: item.bindingVariateName, value: item.value})
    })
    let sender = {
      type: 'multiple',
      data: interactionStreams
    }
    EventBus.$emit('pn_interaction_stream_manual', sender)
  }catch (e) {
    console.error(e)
  }
}

/**
 * 系统自动截图
 * @param domId
 * @param pageId
 * @param successCallback
 * @param errorCallback
 */
const systemScreenShot = function (domId, pageId, successCallback, errorCallback) {
  let dom = document.getElementById(domId)

  const dataURItoBlob = function (dataURI) {
    let byteString = atob(dataURI.split(',')[1])
    let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
    let ab = new ArrayBuffer(byteString.length)
    let ia = new Uint8Array(ab)
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i)
    }
    return new Blob([ab], {type: mimeString})
  }

  html2canvas(dom, {
    backgroundColor: null,
    allowTaint: true,
    useCORS: true
  }).then((canvas) => {
    const dataUrl = canvas.toDataURL('images/png')
    let fd = new FormData()
    let blob = dataURItoBlob(dataUrl)
    fd.append('file', blob, Date.now() + '.png')
    fd.append('pageId', pageId)
    axios({
      url: window.g.AXIOS_BASE_URL + '/file/upload',
      method: 'post',
      data: fd,
      headers: {
        Authorization: localStorage.getItem('token')
      }
    }).then((result) => {
      successCallback(result)
    }).catch(function (error) {
      errorCallback(error)
    });
  })
}

export default {
  uuid,
  getTimestamp,
  dateFormatter,
  openPageToBlank,
  getRootPath,
  jumpLink,
  openIframeModal,
  getContrastYIQ,
  isMac,
  isWindows,
  deleteTableRowUselessField,
  cssToVueStyleObj,
  deepClone,
  addUrlParams,
  deleteUrlParams,
  getUrlParam,
  buildApiPath,
  getCompConfigData,
  getCompBaseAttr,
  getAllFuncCompName,
  imageToBase64,
  deepMerge,
  addImageToLocalStorage,
  getCurrentUser,
  getBrowser,
  cutString,
  buildImageSrc,
  buildDrawerStyleByHasFooter,
  reconsitutionLayoutObj,
  groupArray,
  insertTextAtCursor,
  copyToClipboard,
  getRandomNum,
  asyncHref,
  showMaskLayer,
  insertStyle,
  insertScript,
  loadCSS,
  isDesignerPage,
  manualLaunchInteractionStream,
  multiManualLaunchInteractionStream,
  systemScreenShot
}
